home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Table / Sources / Linking.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  29.4 KB  |  893 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Linking.cpp
  4. //    Release Version:    $ ODF 1 $ 
  5. //
  6. //    Copyright:            (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #ifndef LINKING_H
  11. #include "Linking.h"
  12. #endif
  13.  
  14. #ifndef PART_H
  15. #include "Part.h"
  16. #endif
  17.  
  18. #ifndef SELECTION_H
  19. #include "Selection.h"
  20. #endif
  21.  
  22. #ifndef COMMANDS_H
  23. #include "Commands.h"
  24. #endif
  25.  
  26. #ifndef PROXY_H
  27. #include "Proxy.h"
  28. #endif
  29.  
  30. #ifndef FRAME_H
  31. #include "Frame.h"
  32. #endif
  33.  
  34. #ifndef CONTENT_H
  35. #include "Content.h"
  36. #endif
  37.  
  38. // ----- Framework Includes -----
  39.  
  40. #ifndef FWPART_H
  41. #include "FWPart.h"
  42. #endif
  43.  
  44. #ifndef FWFRAME_H
  45. #include "FWFrame.h"
  46. #endif
  47.  
  48. #ifndef FWITERS_H
  49. #include "FWIters.h"
  50. #endif
  51.  
  52. #ifndef FWPRESEN_H
  53. #include "FWPresen.h"
  54. #endif
  55.  
  56. #ifndef FWSELECT_H
  57. #include "FWSelect.h"
  58. #endif
  59.  
  60. // for FW_CCloneInfo
  61. #ifndef FWPROXY_H
  62. #include "FWProxy.h"
  63. #endif
  64.  
  65. // for FW_SUForceFocus
  66. #ifndef FWUTIL_H
  67. #include "FWUtil.h"
  68. #endif
  69.  
  70. #ifndef FWPXYFRM_H
  71. #include "FWPxyFrm.h"
  72. #endif
  73.  
  74. #ifndef FWPRTITE_H
  75. #include "FWPrtIte.h"
  76. #endif
  77.  
  78. #ifndef FWUTIL_H
  79. #include "FWUtil.h"
  80. #endif
  81.  
  82. #ifndef FWCLNINF_H
  83. #include "FWClnInf.h"
  84. #endif
  85.  
  86. #ifndef FWPXYITE_H
  87. #include "FWPxyIte.h"
  88. #endif
  89.  
  90. #ifndef FWLNKITE_H
  91. #include "FWLnkIte.h"
  92. #endif
  93.  
  94. #ifndef FWINTER_H
  95. #include "FWInter.h"
  96. #endif
  97.  
  98. // ----- OS Includes -----
  99.  
  100. #ifndef FWODEXCE_H
  101. #include "FWODExce.h"
  102. #endif
  103.  
  104. #ifndef FWBARRAY_H
  105. #include "FWBArray.h"
  106. #endif
  107.  
  108. // ----- Foundation Includes -----
  109.  
  110. #ifndef FWMEMMGR_H
  111. #include "FWMemMgr.h"
  112. #endif
  113.  
  114. // ----- OpenDoc Includes -----
  115.  
  116. #ifndef SOM_Module_OpenDoc_StdProps_defined
  117. #include <StdProps.xh>
  118. #endif
  119.  
  120. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  121. #include <StdTypes.xh>
  122. #endif
  123.  
  124. #ifndef SOM_ODStorageUnit_xh
  125. #include <StorageU.xh>
  126. #endif
  127.  
  128. #ifndef SOM_ODStorageUnitView_xh
  129. #include <SUView.xh>
  130. #endif
  131.  
  132. #ifndef SOM_ODLink_xh
  133. #include <Link.xh>
  134. #endif
  135.  
  136. #ifndef SOM_ODLinkSpec_xh
  137. #include <LinkSpec.xh>
  138. #endif
  139.  
  140. #ifndef SOM_ODLinkSource_xh
  141. #include <LinkSrc.xh>
  142. #endif
  143.  
  144. #ifndef SOM_ODSession_xh
  145. #include <ODSessn.xh>
  146. #endif
  147.  
  148. //========================================================================================
  149. // Constants
  150. //========================================================================================
  151.  
  152. #define kPublishFormat "Apple:ODF:Publish:ODFTable"
  153. #define kSubscribeFormat "Apple:ODF:Subscribe:ODFTable"
  154.  
  155. //========================================================================================
  156. // Runtime Information
  157. //========================================================================================
  158.  
  159. #ifdef FW_BUILD_MAC
  160. #pragma segment opftable
  161. #endif
  162.  
  163. //========================================================================================
  164. // Global Functions
  165. //========================================================================================
  166.  
  167. ODShape* CreateLinkBorderShape(Environment* ev, CCell cell, CTableContent* content);
  168. void DrawLinkBorder(Environment* ev, ODShape* outline, FW_CGraphicContext& gc, FW_Boolean selected);
  169.  
  170. //----------------------------------------------------------------------------------------
  171. //    CreateLinkBorderShape
  172. //----------------------------------------------------------------------------------------
  173. ODShape* CreateLinkBorderShape(Environment* ev, CCell cell, CTableContent* content)
  174. {
  175.     FW_CRect rect;
  176.     content->FindRect(cell, rect);
  177.     ODShape* shape = ::FW_NewODShape(ev, rect);
  178.     return shape;
  179. }
  180.  
  181. //----------------------------------------------------------------------------------------
  182. //    DrawLinkBorder
  183. //----------------------------------------------------------------------------------------
  184. void DrawLinkBorder(Environment* ev, ODShape* outline, FW_CGraphicContext& gc, FW_Boolean selected)
  185. {
  186.     FW_CRect box;
  187.     outline->GetBoundingBox(ev, (ODRect*)&box);
  188.  
  189.     FW_CStyle horzStyle(FW_IntToFixed(FW_kLinkBorderWidth), FW_kHLinkPat);
  190.     FW_CStyle vertStyle(FW_IntToFixed(FW_kLinkBorderWidth), FW_kVLinkPat);
  191.     FW_CInk ink(FW_kXOr);
  192.  
  193.     if (selected)
  194.     {
  195.         horzStyle.SetPattern(FW_kSelectedHLinkPat);
  196.         vertStyle.SetPattern(FW_kSelectedVLinkPat);
  197.     }
  198.  
  199.     FW_CLineShape topLine(box.TopLeft(), box.TopRight(), ink, horzStyle);
  200.     FW_CLineShape bottomLine(box.BotLeft(), box.BotRight(), ink, horzStyle);
  201.     FW_CLineShape leftLine(box.TopLeft(), box.BotLeft(), ink, vertStyle);
  202.     FW_CLineShape rightLine(box.TopRight(), box.BotRight(), ink, vertStyle);
  203.  
  204.     topLine.Render(gc);
  205.     bottomLine.Render(gc);
  206.     leftLine.Render(gc);
  207.     rightLine.Render(gc);
  208. }
  209.  
  210. //========================================================================================
  211. //    class CTableLinkSource
  212. //========================================================================================
  213.  
  214. //----------------------------------------------------------------------------------------
  215. //    CTableLinkSource constructor
  216. //----------------------------------------------------------------------------------------
  217.  
  218. CTableLinkSource::CTableLinkSource(    Environment* ev, ODUpdateID changeID, 
  219.                                     FW_CPresentation* presentation,
  220.                                     CTablePart* part,
  221.                                     CTableContent* content,
  222.                                     CTableSelection* selection)
  223. :    FW_CLinkSource(ev, changeID, presentation),
  224.     fTablePart(part),
  225.     fPublishedContent(NULL)
  226. {
  227.     fPublishedContent = FW_NEW(CTableSelectionContent, (ev, part, content));
  228.     fPublishedContent->SetCell(selection->GetSelectedCell());
  229. }
  230.  
  231. //----------------------------------------------------------------------------------------
  232. //    CTableLinkSource destructor
  233. //----------------------------------------------------------------------------------------
  234.  
  235. CTableLinkSource::~CTableLinkSource()
  236. {
  237. }
  238.  
  239. //----------------------------------------------------------------------------------------
  240. //    CTableLinkSource::LinkEstablished
  241. //----------------------------------------------------------------------------------------
  242.  
  243. void CTableLinkSource::LinkEstablished(Environment* ev)
  244. {
  245.     //---- Change the link status of affected embedded frames
  246.     fTablePart->ChangeFrameStatus(ev, fPublishedContent->GetCell(), kODInLinkSource);
  247. }
  248.  
  249. //----------------------------------------------------------------------------------------
  250. //    CTableLinkSource::DoExternalizeLink
  251. //----------------------------------------------------------------------------------------
  252.  
  253. void CTableLinkSource::DoExternalizeLink(Environment* ev, ODStorageUnit* storageUnit,
  254.                                          FW_CCloneInfo* cloneInfo)
  255. {
  256.     //-- Write out data specific to this part's publisher --
  257.     CCell cell = fPublishedContent->GetCell();        // table cell associated with this publisher
  258.     FW_CByteArray byteArray(&cell, sizeof(CCell));
  259.     storageUnit->SetValue(ev, byteArray);
  260. }
  261.  
  262. //----------------------------------------------------------------------------------------
  263. //    CTableLinkSource::ExternalizeLinkContent
  264. //----------------------------------------------------------------------------------------
  265.  
  266. void CTableLinkSource::ExternalizeLinkContent(Environment* ev, ODStorageUnit* linkSU)
  267. {
  268.     // Remove any properties which  FW_CEmbeddingSelection::DoExternalizeSingleEmbeddedFrame 
  269.     // expects to find missing.  
  270.     // ODLinkSource::Clear removed only the content property.
  271.     FW_SURemoveProperty(ev, linkSU, kODPropContentFrame);
  272.  
  273.     // -- Pick a frame, any frame --
  274.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  275.     FW_CFrame* frame = piter.First(ev);
  276.     FW_ASSERT(frame);
  277.  
  278.     fDataInterchange->ExternalizeData(ev, fPublishedContent, frame, linkSU, FW_kLinkStorage, kODCloneToLink);
  279. }
  280.  
  281. //----------------------------------------------------------------------------------------
  282. //    CTableLinkSource::GetFrameToRevealLink
  283. //----------------------------------------------------------------------------------------
  284. FW_CFrame* CTableLinkSource::GetFrameToRevealLink(Environment* ev)
  285. {
  286.     // By default, return the presentation's first display frame
  287.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  288.     return piter.First(ev);
  289. }
  290.  
  291. //----------------------------------------------------------------------------------------
  292. //    CTableLinkSource::HasEmbeddedFrame
  293. //---------------------------------------------------------------------------------------
  294. FW_Boolean CTableLinkSource::HasEmbeddedFrame(Environment* ev, ODFrame* odFrame)
  295. {
  296.     // Is odFrame involved in this link source? (called by Part::EmbeddedFrameChanged)
  297.  
  298.     FW_Boolean result = false;
  299.  
  300.     // --- Find out whether odFrame is involved in any link source ---
  301.     if (odFrame->GetLinkStatus(ev) == kODInLinkSource)
  302.     {
  303.         // -- Find out whether odFrame is one of my frames --
  304.         FW_CFrame* fwFrame = FW_CFrame::ODtoFWFrame(ev, odFrame);
  305.         if (fwFrame)
  306.         {
  307.             CTableProxy* proxy = fPublishedContent->GetSelectedProxy(ev);
  308.             FW_CProxyProxyFrameIterator iter((FW_MProxy*) proxy);
  309.             for (FW_CProxyFrame* proxyFrame = iter.First(); iter.IsNotComplete(); proxyFrame = iter.Next())
  310.                 if (proxyFrame->GetFrame(ev) == odFrame)
  311.                 {
  312.                     result = true;
  313.                     break;
  314.                 }
  315.         }
  316.     }
  317.  
  318.     return result;
  319. }
  320.  
  321. //----------------------------------------------------------------------------------------
  322. // CTableLinkSource::DoLinkInfo
  323. //----------------------------------------------------------------------------------------
  324. CBreakLinkSourceCommand* CTableLinkSource::DoLinkInfo(Environment* ev, ODFacet* facet)
  325. {
  326.     CBreakLinkSourceCommand* cmd = NULL;
  327.     ODLinkInfoResult infoResult;
  328.  
  329.     if (fODLinkSource->ShowLinkSourceInfo(ev, facet, fODLinkSource->GetUpdateID(ev), true, &infoResult))
  330.     {
  331.         switch (infoResult.action)
  332.         {
  333.             case kODLinkInfoBreakLink:
  334.               {
  335.                 // Create and return an undoable command to break the link
  336.                 FW_CFrame* frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
  337.                 cmd = FW_NEW(CBreakLinkSourceCommand, (ev, frame, this)); 
  338.               }
  339.                 break;
  340.             case kODLinkInfoUpdateNow:
  341.                 this->ContentUpdated(ev, fUpdateID, true);
  342.                 break;
  343.             case kODLinkInfoOk:
  344.                 if (infoResult.autoUpdate != fODLinkSource->IsAutoUpdate(ev))
  345.                 {
  346.                     fODLinkSource->SetAutoUpdate(ev, infoResult.autoUpdate);
  347.                     if (infoResult.autoUpdate)
  348.                         if (fUpdateID != fODLinkSource->GetUpdateID(ev))
  349.                             // changed from manual to automatic updates, and
  350.                             // the link is out of date-- update it now
  351.                             this->ContentUpdated(ev, fODLinkSource->GetUpdateID(ev), true);
  352.                 }
  353.                 break;
  354.         }
  355.     }
  356.  
  357.     return cmd;    // cmd is non-NULL if user said to break the link
  358. }
  359.  
  360. //----------------------------------------------------------------------------------------
  361. // CTableLinkSource::BreakLink
  362. //----------------------------------------------------------------------------------------
  363. void CTableLinkSource::BreakLink(Environment* ev)
  364. {
  365.     FW_CLinkSource::BreakLink(ev);
  366.  
  367.     //--- Erase Link Borders ---
  368.     fPresentation->Invalidate(ev);    // force all frames to be redrawn
  369.  
  370.     //--- Change status of embedded frames ---
  371.     fTablePart->ChangeFrameStatus(ev, fPublishedContent->GetCell(), kODNotInLink);
  372. }
  373.  
  374. //----------------------------------------------------------------------------------------
  375. //    CTableLinkSource::DoSelect
  376. //----------------------------------------------------------------------------------------
  377. void CTableLinkSource::DoSelect(Environment* ev, FW_CFrame* /*frame*/)
  378. {
  379.     CTableSelection* selection = fTablePart->GetTableSelection(ev);
  380.     selection->Select(ev, fPublishedContent->GetCell());
  381. }
  382.  
  383. //----------------------------------------------------------------------------------------
  384. // CTableLinkSource::GetCell
  385. //----------------------------------------------------------------------------------------
  386. CCell CTableLinkSource::GetCell(Environment* ev) const
  387. {
  388.     return fPublishedContent->GetCell();
  389. }
  390.  
  391. //----------------------------------------------------------------------------------------
  392. // CTableLinkSource::SetCell
  393. //----------------------------------------------------------------------------------------
  394. void CTableLinkSource::SetCell(Environment* ev, const CCell& cell)
  395. {
  396.     fPublishedContent->SetCell(cell);
  397. }
  398.  
  399. //----------------------------------------------------------------------------------------
  400. // CTableLinkSource::DoCreateLinkBorderShape
  401. //----------------------------------------------------------------------------------------
  402. ODShape* CTableLinkSource::DoCreateLinkBorderShape(Environment* ev)
  403. {
  404.     return CreateLinkBorderShape(ev, GetCell(ev), fTablePart->GetTableContent(ev));
  405. }
  406.  
  407. //----------------------------------------------------------------------------------------
  408. // CTableLinkSource::DoDrawLinkBorder
  409. //----------------------------------------------------------------------------------------
  410. void CTableLinkSource::DoDrawLinkBorder(Environment* ev, ODShape* outline, FW_CGraphicContext& gc)
  411. {
  412.     DrawLinkBorder(ev, outline, gc, this->IsLinkSelected(ev));
  413. }
  414.  
  415. //========================================================================================
  416. //    class CTableLink
  417. //========================================================================================
  418.  
  419. //----------------------------------------------------------------------------------------
  420. //    CTableLink constructor
  421. //----------------------------------------------------------------------------------------
  422.  
  423. CTableLink::CTableLink(    Environment* ev, 
  424.                         ODLink* odLink,
  425.                         ODLinkInfo* linkInfo, 
  426.                         FW_CPresentation* presentation,
  427.                         CTablePart* part,
  428.                         CTableContent* content,
  429.                         CTableSelection* selection) 
  430. :    FW_CLinkDestination(ev, odLink, linkInfo, presentation),
  431.     fTablePart(part),
  432.     fLinkedContent(NULL)
  433. {
  434.     //---- Create a new content object ----
  435.     fLinkedContent = FW_NEW(CTableSelectionContent, (ev, part, content));
  436.     fLinkedContent->SetCell(selection->GetSelectedCell());
  437. }
  438.  
  439. //----------------------------------------------------------------------------------------
  440. //    CTableLink destructor
  441. //----------------------------------------------------------------------------------------
  442.  
  443. CTableLink::~CTableLink()
  444. {
  445. }
  446.  
  447. //----------------------------------------------------------------------------------------
  448. //    CTableLink::LinkEstablished
  449. //----------------------------------------------------------------------------------------
  450.  
  451. void CTableLink::LinkEstablished(Environment* ev)
  452. {
  453.     fTablePart->ChangeFrameStatus(ev, fLinkedContent->GetCell(), kODInLinkDestination);
  454. }
  455.  
  456. //----------------------------------------------------------------------------------------
  457. //    CTableLink::DoUpdateLink
  458. //--------------------------------------------------------------------
  459. FW_Boolean CTableLink::DoUpdateLink(Environment* ev, ODStorageUnit* linkContentSU, ODPasteAsResult* embedInfo)
  460. {
  461.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  462.     FW_CFrame* frame = piter.First(ev);
  463.     FW_ASSERT(frame);
  464.  
  465.     //-- Read data from the linkContentSU --
  466.     FW_Boolean result = (fDataInterchange->InternalizeData(ev, fLinkedContent, frame, linkContentSU, 
  467.                                                     FW_kLinkStorage, kODCloneFromLink, embedInfo)
  468.                                                     != FW_kInternalizeFailed);
  469.     if (result)
  470.         fPresentation->Invalidate(ev);    // force all frames to be redrawn
  471.     return result;
  472. }
  473.  
  474. //----------------------------------------------------------------------------------------
  475. // CTableLink::DoLinkInfo
  476. //----------------------------------------------------------------------------------------
  477. CBreakLinkCommand* CTableLink::DoLinkInfo(Environment* ev, ODFacet* facet)
  478. {
  479.     CBreakLinkCommand* cmd = NULL;
  480.     ODLinkInfoResult infoResult;
  481.         
  482.     if (fODLink->ShowLinkDestinationInfo(ev, facet, &fLinkInfo, true, &infoResult))
  483.     {
  484.         switch (infoResult.action)
  485.         {
  486.             case kODLinkInfoFindSource:
  487.                 fODLink->ShowSourceContent(ev);
  488.                 break;
  489.             case kODLinkInfoBreakLink: 
  490.               {
  491.                 // Create and return an undoable command to break the link
  492.                 FW_CFrame* frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
  493.                 cmd = FW_NEW(CBreakLinkCommand, (ev, frame, this)); 
  494.               }
  495.                 break;
  496.             case kODLinkInfoUpdateNow:
  497.                 this->LinkUpdated(ev, fODLink->GetUpdateID(ev));
  498.                 break;
  499.             case kODLinkInfoOk:
  500.                 if (infoResult.autoUpdate != fLinkInfo.autoUpdate)
  501.                 {
  502.                     fLinkInfo.autoUpdate = infoResult.autoUpdate;
  503.                     this->Register(ev, fTablePart);
  504.                 }
  505.                 break;
  506.         }
  507.     }
  508.  
  509.     return cmd;    // cmd is non-NULL if user said to break the link
  510. }
  511.  
  512. //----------------------------------------------------------------------------------------
  513. // CTableLink::BreakLink
  514. //----------------------------------------------------------------------------------------
  515. void CTableLink::BreakLink(Environment* ev)
  516. {
  517.     FW_CLinkDestination::BreakLink(ev);
  518.  
  519.     //--- Erase Link Borders ---
  520.     fPresentation->Invalidate(ev);    // force all frames to be redrawn
  521.  
  522.     //--- Change status of embedded frames ---
  523.     fTablePart->ChangeFrameStatus(ev, fLinkedContent->GetCell(), kODNotInLink);
  524. }
  525.  
  526. //----------------------------------------------------------------------------------------
  527. //    CTableLink::DoExternalizeLink
  528. //----------------------------------------------------------------------------------------
  529.  
  530. void CTableLink::DoExternalizeLink(Environment* ev, ODStorageUnit* storageUnit, FW_CCloneInfo* cloneInfo)
  531. {
  532.     // Write out data specific to this part's subscriber
  533.     CCell cell = fLinkedContent->GetCell();                // table cell associated with this link
  534.     FW_CByteArray byteArray(&cell, sizeof(CCell));
  535.     storageUnit->SetValue(ev, byteArray);
  536. }
  537.  
  538. //----------------------------------------------------------------------------------------
  539. // CTableLink::GetCell
  540. //----------------------------------------------------------------------------------------
  541. CCell CTableLink::GetCell(Environment* ev) const
  542. {
  543.     return fLinkedContent->GetCell();
  544. }
  545.  
  546. //----------------------------------------------------------------------------------------
  547. // CTableLink::SetCell
  548. //----------------------------------------------------------------------------------------
  549. void CTableLink::SetCell(Environment* ev, const CCell& cell)
  550. {
  551.     fLinkedContent->SetCell(cell);
  552. }
  553.  
  554. //----------------------------------------------------------------------------------------
  555. // CTableLink::DoCreateLinkBorderShape
  556. //----------------------------------------------------------------------------------------
  557. ODShape* CTableLink::DoCreateLinkBorderShape(Environment* ev)
  558. {
  559.     return CreateLinkBorderShape(ev, GetCell(ev), fTablePart->GetTableContent(ev));
  560. }
  561.  
  562. //----------------------------------------------------------------------------------------
  563. // CTableLink::DoDrawLinkBorder
  564. //----------------------------------------------------------------------------------------
  565. void CTableLink::DoDrawLinkBorder(Environment* ev, ODShape* outline, FW_CGraphicContext& gc)
  566. {
  567.     DrawLinkBorder(ev, outline, gc, this->IsLinkSelected(ev));
  568. }
  569.  
  570. //========================================================================================
  571. //    class CTableLinkManager
  572. //========================================================================================
  573.  
  574. FW_DEFINE_AUTO(CTableLinkManager)
  575.  
  576. //----------------------------------------------------------------------------------------
  577. //    CTableLinkManager constructor
  578. //----------------------------------------------------------------------------------------
  579.  
  580. CTableLinkManager::CTableLinkManager(Environment* ev, CTablePart* thePart, CTableContent* tableContent) :
  581.     FW_CLinkManager(ev, (FW_CPart*)thePart),
  582.     fTablePart(thePart),
  583.     fTableContent(tableContent)
  584. {
  585. }
  586.  
  587. //----------------------------------------------------------------------------------------
  588. //    CTableLinkManager destructor
  589. //----------------------------------------------------------------------------------------
  590.  
  591. CTableLinkManager::~CTableLinkManager()
  592. {
  593. }
  594.  
  595. //----------------------------------------------------------------------------------------
  596. //    CTableLinkManager::NewLinkSource
  597. //----------------------------------------------------------------------------------------
  598.  
  599. FW_CLinkSource* CTableLinkManager::NewLinkSource(Environment* ev, 
  600.                                                  ODUpdateID changeID, 
  601.                                                  FW_CPresentation* presentation)
  602. {
  603.     return new CTableLinkSource(ev, changeID, presentation, fTablePart, fTableContent, fTablePart->GetTableSelection(ev));
  604. }
  605.  
  606. //----------------------------------------------------------------------------------------
  607. //    CTableLinkManager::NewLinkDestination
  608. //----------------------------------------------------------------------------------------
  609.  
  610. FW_CLinkDestination* CTableLinkManager::NewLinkDestination(Environment* ev, ODLink *odLink,
  611.                                                         ODLinkInfo* linkInfo,
  612.                                                         FW_CPresentation* presentation)
  613. {
  614.     return new CTableLink(ev, odLink, linkInfo, presentation, fTablePart, fTableContent, fTablePart->GetTableSelection(ev));
  615. }
  616.  
  617. //----------------------------------------------------------------------------------------
  618. //    CTableLinkManager::DoChangeLinkStatus
  619. //----------------------------------------------------------------------------------------
  620.  
  621. void CTableLinkManager::DoChangeLinkStatus(Environment* ev, ODFrame* odFrame)
  622. {
  623.     // call ODFrame::ChangeLinkStatus on any embedded frames that are involved in a link
  624.     // when a link is created, broken, moved, etc.
  625.     // odFrame is the frame of this part whose link status has changed.
  626.     
  627.     FW_CEmbeddingFrame* frame = FW_CEmbeddingFrame::ODtoFWEmbeddingFrame(ev, odFrame);
  628.     if (frame)
  629.     {
  630.         ODLinkStatus linkStatus = odFrame->GetLinkStatus(ev);
  631.  
  632.         // Only need to propagate linkStatus to embedded frames that don't participate in
  633.         // any of this part's links; otherwise their local link status takes precedence.
  634.  
  635.         CTableProxysIterator iter(fTableContent);
  636.         for (CTableProxy* proxy = iter.First(); iter.IsNotComplete(); proxy = iter.Next())
  637.         {
  638.             if (!this->IsCellInLink(ev, proxy->GetCell()))
  639.             {
  640.                 FW_CProxyEmbeddedFrameIterator efiter(ev, proxy);
  641.                 for (ODFrame* embFrame = efiter.First(ev); efiter.IsNotComplete(ev); embFrame = efiter.Next(ev))
  642.                     embFrame->ChangeLinkStatus(ev, linkStatus);
  643.             }
  644.         }
  645.     }
  646. }
  647.  
  648. //----------------------------------------------------------------------------------------
  649. //    CTableLinkManager::GetSourceLinkFormat, GetDestLinkFormat
  650. //----------------------------------------------------------------------------------------
  651. ODValueType    CTableLinkManager::GetSourceLinkFormat(Environment* ev)
  652. {
  653.     // Must be different from subscribe format!
  654.     return kPublishFormat;
  655. }
  656.  
  657. ODValueType    CTableLinkManager::GetDestLinkFormat(Environment* ev)
  658. {
  659.     // Must be different from publish format!
  660.     return kSubscribeFormat;
  661. }
  662.  
  663. //----------------------------------------------------------------------------------------
  664. //    CTableLinkManager::RevealLink
  665. //----------------------------------------------------------------------------------------
  666.  
  667. void CTableLinkManager::RevealLink(Environment* ev, ODLinkSource* linkSource)
  668. {
  669.     CTableLinkSource* sourceLink = (CTableLinkSource*) ODtoFWLinkSource(ev, linkSource);
  670.     FW_ASSERT(sourceLink);
  671.  
  672.     // Choose a display frame for the source content
  673.     FW_CFrame* frame = sourceLink->GetFrameToRevealLink(ev);
  674.     if (frame)
  675.     {
  676.         // ----- Activate the frame's window -----
  677.         if (!frame->GetWindow(ev)->IsActive(ev))
  678.             frame->GetWindow(ev)->Select(ev);        
  679.     
  680.         // ----- Activate the frame -----
  681.         if (!frame->HasSelectionFocus(ev))
  682.         {
  683.             FW_CFrameFacetIterator iter(ev, frame);    // find a facet
  684.             frame->PrivActivateFrame(ev, iter.First(ev));
  685.         }
  686.  
  687.         // ----- Select the link source -----
  688.         sourceLink->DoSelect(ev, frame);
  689.     }
  690. }
  691.  
  692.  
  693. //----------------------------------------------------------------------------------------
  694. //    CTableLinkManager::IsCellInLink
  695. //----------------------------------------------------------------------------------------
  696. FW_Boolean CTableLinkManager::IsCellInLink(Environment* ev, const CCell& cell)
  697. {
  698.     //--- Check whether the cell participates in any of our source links
  699.     FW_CLinkMgrLinkSourceIterator sit(this);
  700.     for (CTableLinkSource* publisher = (CTableLinkSource*)sit.First(); sit.IsNotComplete(); 
  701.             publisher = (CTableLinkSource*)sit.Next())
  702.     {
  703.         if (publisher->GetCell(ev) == cell)
  704.             return true;
  705.     }
  706.  
  707.     //--- Check whether the cell participates in any of our destination links
  708.     FW_CLinkMgrLinkDestIterator dit(this);
  709.     for (CTableLink* link = (CTableLink*)dit.First(); dit.IsNotComplete(); link = (CTableLink*)dit.Next())
  710.     {
  711.         if (link->GetCell(ev) == cell)
  712.             return true;
  713.     }
  714.  
  715.     return false;
  716. }
  717.  
  718. //----------------------------------------------------------------------------------------
  719. // CTableLinkManager::CellToSourceLink
  720. //----------------------------------------------------------------------------------------
  721. CTableLinkSource* CTableLinkManager::CellToSourceLink(Environment* ev, const CCell& cell) const
  722. {
  723.     FW_CLinkMgrLinkSourceIterator iter(this);
  724.     for (CTableLinkSource* slink = (CTableLinkSource*)iter.First(); iter.IsNotComplete(); 
  725.             slink = (CTableLinkSource*)iter.Next())
  726.     {
  727.         if (slink->GetCell(ev) == cell)
  728.             return slink;
  729.     }
  730.  
  731.     return NULL;
  732. }
  733.  
  734. //----------------------------------------------------------------------------------------
  735. // CTableLinkManager::CellToLink
  736. //----------------------------------------------------------------------------------------
  737. CTableLink* CTableLinkManager::CellToLink(Environment* ev, const CCell& cell) const
  738. {
  739.     FW_CLinkMgrLinkDestIterator iter(this);
  740.     for (CTableLink* link = (CTableLink*)iter.First(); iter.IsNotComplete(); 
  741.             link = (CTableLink*)iter.Next())
  742.     {
  743.         if (link->GetCell(ev) == cell)
  744.             return link;
  745.     }
  746.  
  747.     return NULL;
  748. }
  749.  
  750. //----------------------------------------------------------------------------------------
  751. // CTableLinkManager::ShowLinkInfo
  752. //----------------------------------------------------------------------------------------
  753.  
  754. FW_Boolean CTableLinkManager::ShowLinkInfo(Environment* ev, ODFacet* facet)
  755. {
  756.     FW_Boolean handledIt = true;
  757.  
  758.     CTableLinkSource* publisher = this->GetSelectedLinkSource(ev);
  759.     if (publisher)
  760.     {
  761.         CBreakLinkSourceCommand* cmd = publisher->DoLinkInfo(ev, facet);
  762.         if (cmd)
  763.             cmd->Execute(ev);    // break the link
  764.     }
  765.     else
  766.     {
  767.         CTableLink* subscriber = this->GetSelectedLinkDest(ev);
  768.         if (subscriber)
  769.         {
  770.             CBreakLinkCommand* cmd = subscriber->DoLinkInfo(ev, facet);
  771.             if (cmd)
  772.                 cmd->Execute(ev);    // break the link
  773.         }
  774.         else 
  775.             handledIt = false;
  776.     }
  777.  
  778.     return handledIt;
  779. }
  780.  
  781. //----------------------------------------------------------------------------------------
  782. //    CTableLinkManager::GetSelectedLinkSource
  783. //----------------------------------------------------------------------------------------
  784. CTableLinkSource* CTableLinkManager::GetSelectedLinkSource(Environment* ev)
  785. {
  786.     /* for now, return a link source if its cell is selected */
  787.     CTableSelection* selection = fTablePart->GetTableSelection(ev);
  788.     return this->CellToSourceLink(ev, selection->GetSelectedCell());
  789. }
  790.  
  791. //----------------------------------------------------------------------------------------
  792. //    CTableLinkManager::GetSelectedLinkDest
  793. //----------------------------------------------------------------------------------------
  794. CTableLink* CTableLinkManager::GetSelectedLinkDest(Environment* ev)
  795. {
  796.     /* for now, return a link if its cell is selected */
  797.     CTableSelection* selection = fTablePart->GetTableSelection(ev);
  798.     return this->CellToLink(ev, selection->GetSelectedCell());
  799. }
  800.  
  801. //----------------------------------------------------------------------------------------
  802. //    CTableLinkManager::DoInternalizeOneSourceLink
  803. //---------------------------------------------------------------------------------------
  804.  
  805. FW_CLinkSource* CTableLinkManager::DoInternalizeOneSourceLink(Environment* ev, 
  806.                                                               ODStorageUnit* storageUnit,
  807.                                                               ODUpdateID updateID)
  808. {
  809.     //-- Read the link source's cell
  810.     CCell cell;
  811.     FW_CByteArray byteArray;
  812.     storageUnit->GetValue(ev, sizeof(CCell), byteArray);
  813.     byteArray.CopyBuffer(&cell, sizeof(CCell));
  814.  
  815.     //-- Create and add a publisher to represent the link source
  816.     CTableLinkSource* publisher = (CTableLinkSource*)this->NewLinkSource(ev, 
  817.                                         updateID, fTablePart->fTablePresentation);
  818.     publisher->SetCell(ev, cell);
  819.     fTablePart->ChangeFrameStatus(ev, cell, kODInLinkSource);
  820.  
  821.     return publisher;
  822. }
  823.  
  824. //----------------------------------------------------------------------------------------
  825. //    CTableLinkManager::DoInternalizeOneDestLink
  826. //---------------------------------------------------------------------------------------
  827.  
  828. FW_CLinkDestination* CTableLinkManager::DoInternalizeOneDestLink(Environment* ev, 
  829.                                                                ODStorageUnit* storageUnit,
  830.                                                                ODLink* odLink, 
  831.                                                                ODLinkInfo* linkInfo)
  832. {
  833.     //-- Read the link's cell
  834.     CCell cell;
  835.     FW_CByteArray byteArray;
  836.     storageUnit->GetValue(ev, sizeof(CCell), byteArray);
  837.     byteArray.CopyBuffer(&cell, sizeof(CCell));
  838.  
  839.     //-- Create and add a subscriber to represent the link
  840.     CTableLink* subscriber = (CTableLink*)this->NewLinkDestination(ev, 
  841.                                             odLink, linkInfo, fTablePart->fTablePresentation);
  842.     subscriber->SetCell(ev, cell);
  843.     return subscriber;
  844. }
  845.  
  846. //----------------------------------------------------------------------------------------
  847. //    CTableLinkManager::UpdateLinkSource
  848. //----------------------------------------------------------------------------------------
  849.  
  850. void CTableLinkManager::UpdateLinkSource(Environment* ev, ODUpdateID updateID)
  851. {
  852.     CTableLinkSource* linkSource = this->GetSelectedLinkSource(ev);
  853.     if (linkSource)
  854.         linkSource->ContentUpdated(ev, updateID, true);
  855. }
  856.  
  857. //----------------------------------------------------------------------------------------
  858. //    CTableLinkManager::BreakExistingLinks
  859. //----------------------------------------------------------------------------------------
  860. void CTableLinkManager::BreakExistingLinks(Environment* ev, const CCell& cell)
  861. {
  862.     //-- Check for a link being broken --
  863.     CTableLinkSource* linkSource = this->CellToSourceLink(ev, cell);
  864.     if (linkSource)
  865.     {
  866.         this->BreakSourceLink(ev, linkSource);
  867.         delete linkSource;
  868.     }
  869.     CTableLink* link = this->CellToLink(ev, cell);
  870.     if (link)
  871.     {
  872.         this->BreakDestinationLink(ev, link);
  873.         delete link;
  874.     }
  875. }
  876.  
  877. //----------------------------------------------------------------------------------------
  878. //    CTableLinkManager::MoveExistingLinks
  879. //----------------------------------------------------------------------------------------
  880. void CTableLinkManager::MoveExistingLinks(Environment* ev,
  881.                                           const CCell& fromCell,
  882.                                           const CCell& toCell)
  883. {
  884.     //-- Adjust affected links --
  885.     CTableLinkSource* slink = this->CellToSourceLink(ev, fromCell);
  886.     if (slink)
  887.         slink->SetCell(ev, toCell);
  888.     CTableLink* link = this->CellToLink(ev, fromCell);
  889.     if (link)
  890.         link->SetCell(ev, toCell);
  891. }
  892.  
  893.